#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Utilities.Miscellaneous;
using System.IO;
using Utilities.Testing;
using Utilities.Text;

namespace Utilities.Test.Miscellaneous
{
  public class ValidationUtilsFixture : TestFixtureBase
  {
    [Test]
    [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null.
Parameter name: TestArgument")]
    public void ValidateArgumentNotNullWithNull()
    {
      ValidationUtils.ArgumentNotNull(null, "TestArgument");
    }

    [Test]
    public void ValidateArgumentNotNullWithNotNull()
    {
      ValidationUtils.ArgumentNotNull(new object(), "TestArgument");
    }

    [Test]
    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Type System.Object is not an Enum.
Parameter name: TestArgument")]
    public void ValidateArgumentEnumTypeWithObject()
    {
      ValidationUtils.ArgumentTypeIsEnum(typeof(object), "TestArgument");
    }

    [Test]
    public void ValidateArgumentEnumTypeWithEnum()
    {
      ValidationUtils.ArgumentTypeIsEnum(typeof(StringComparison), "TestArgument");
    }

    [Test]
    [ExpectedException(typeof(ArgumentNullException), ExpectedMessage = @"Value cannot be null.
Parameter name: TestArgument")]
    public void ValidateArgumentNotNullOrEmptyWithNull()
    {
      ValidationUtils.ArgumentNotNullOrEmpty((ICollection)null, "TestArgument");
    }

    [Test]
    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"'TestArgument' cannot be empty.
Parameter name: TestArgument")]
    public void ValidateArgumentNotNullOrEmptyWithEmpty()
    {
      ValidationUtils.ArgumentNotNullOrEmpty(string.Empty, "TestArgument");
    }

    [Test]
    public void ValidateArgumentNotNullOrEmptyWithNotEmpty()
    {
      ValidationUtils.ArgumentNotNullOrEmpty("Pie", "TestArgument");
    }

    [Test]
    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"'TestArgument' cannot only be whitespace.
Parameter name: TestArgument")]
    public void ValidateArgumentNotNullOrEmptyOrWhitespaceWithWhitespace()
    {
      ValidationUtils.ArgumentNotNullOrEmptyOrWhitespace("  \t " + StringUtils.LineFeed, "TestArgument");
    }

    [Test]
    public void ValidateArgumentNotNullOrEmptyOrWhitespaceWithNonWhitespace()
    {
      ValidationUtils.ArgumentNotNullOrEmptyOrWhitespace("  \t " + StringUtils.LineFeed + "Pie", "TestArgument");
    }

    [Test]
    [ExpectedException(typeof(ObjectDisposedException), ExpectedMessage = @"Cannot access a disposed object.
Object name: 'StreamReader'.")]
    public void ValidateObjectNotDisposedWithDisposed()
    {
      ValidationUtils.ObjectNotDisposed(true, typeof(StreamReader));
    }

    [Test]
    public void ValidateObjectNotDisposedWithNotDisposed()
    {
      ValidationUtils.ObjectNotDisposed(false, typeof(StreamReader));
    }

    [Test]
    public void ArgumentIsPositive()
    {
      ValidationUtils.ArgumentIsPositive<int>(1, "TestParameterName");
      ValidationUtils.ArgumentIsPositive<double>(0.5, "TestParameterName");
      ValidationUtils.ArgumentIsPositive<decimal>(0.00001m, "TestParameterName");
      ValidationUtils.ArgumentIsPositive<DateTime>(new DateTime(2002, 2, 28), "TestParameterName");
      ValidationUtils.ArgumentIsPositive<TimeSpan>(TimeSpan.FromTicks(1), "TestParameterName");
      ValidationUtils.ArgumentIsPositive<Guid>(Guid.NewGuid(), "TestParameterName");
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Positive number required.
Parameter name: TestParameterName
Actual value was 0.")]
    public void ArgumentIsPositiveZeroInt()
    {
      ValidationUtils.ArgumentIsPositive<int>(0, "TestParameterName");
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Positive number required.
Parameter name: TestParameterName
Actual value was -Infinity.")]
    public void ArgumentIsPositiveNegitiveInfinityDouble()
    {
      ValidationUtils.ArgumentIsPositive<double>(double.NegativeInfinity, "TestParameterName");
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Positive number required.
Parameter name: TestParameterName
Actual value was NaN.")]
    public void ArgumentIsPositiveNegitiveNaNSingle()
    {
      ValidationUtils.ArgumentIsPositive<float>(float.NaN, "TestParameterName");
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Positive number required.
Parameter name: TestParameterName
Actual value was 1/01/0001 12:00:00 a.m..")]
    public void ArgumentIsPositiveNegitiveMinValueDateTime()
    {
      ValidationUtils.ArgumentIsPositive<DateTime>(DateTime.MinValue, "TestParameterName");
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"Positive number required.
Parameter name: TestParameterName
Actual value was 00000000-0000-0000-0000-000000000000.")]
    public void ArgumentIsPositiveNegitiveEmptyGuid()
    {
      ValidationUtils.ArgumentIsPositive<Guid>(Guid.Empty, "TestParameterName");
    }

    [Test]
    public void ArgumentIsLess()
    {
      ValidationUtils.ArgumentIsLess<int>(0, 1, "value", "Error!");
    }

    [Test]
    public void ArgumentIsLessEquals()
    {
      ValidationUtils.ArgumentIsLess<DateTime>(new DateTime(2000, 1, 12), new DateTime(2002, 1, 12), "value", "Error!");
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"minValue cannot be greater than or equal to maxValue.
Parameter name: minValue
Actual value was 0.")]
    public void ArgumentIsLessErrorDefaultMessage()
    {
      int argumentValue = 0;
      string argumentName = "minValue";

      ValidationUtils.ArgumentIsLess<int>(1, argumentValue, "minValue", "maxValue", argumentName);
    }

    [Test]
    public void ArgumentIsLessOrEqual()
    {
      ValidationUtils.ArgumentIsLessOrEqual<int>(0, 1, "value", "Error!");
      ValidationUtils.ArgumentIsLessOrEqual<int>(1, 1, "value", "Error!");
    }

    [Test]
    public void ArgumentIsGreater()
    {
      ValidationUtils.ArgumentIsGreater<int>(5, -10, "value", "Error!");
      ValidationUtils.ArgumentIsGreater<int>(-5, -10, "value", "Error!");
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"lesser cannot be less than or equal to greater.
Parameter name: value
Actual value was 5.")]
    public void ArgumentIsGreaterLessThan()
    {
      ValidationUtils.ArgumentIsGreater<int>(-10, 5, "lesser", "greater", "value");
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"lesser cannot be less than or equal to greater.
Parameter name: value
Actual value was -10.")]
    public void ArgumentIsGreaterEquals()
    {
      ValidationUtils.ArgumentIsGreater<int>(-10, -10, "lesser", "greater", "value");
    }

    [Test]
    public void ArgumentIsGreaterOrEqual()
    {
      ValidationUtils.ArgumentIsGreaterOrEqual<int>(5, -10, "value", "Error!");
      ValidationUtils.ArgumentIsGreaterOrEqual<int>(-5, -5, "value", "Error!");
    }

    [Test]
    [ExpectedException(typeof(ArgumentOutOfRangeException), ExpectedMessage = @"lesser cannot be less than greater.
Parameter name: value
Actual value was 5.")]
    public void ArgumentIsGreaterOrEqualLessThan()
    {
      ValidationUtils.ArgumentIsGreaterOrEqual<int>(-10, 5, "lesser", "greater", "value");
    }
  }
}
